#include    "ota_http.h"
#include    "http_curl.h"
#include    <stdlib.h>
#include    <string.h>
#include    "log/log.h"
#include    "json/cJSON.h"
#include    <stdio.h>
#include <openssl/sha.h>
 
/**
 * 通过libcurl 实现http下载
 * 可以从服务器下载版本号
 * 可以从服务器下载ota包
 */

#define BUFFER_SIZE 1024
static int calcSHA( char *filename,char *sha)
{
    FILE *fp = fopen(filename, "rb");
    if (fp==NULL)
    {
        log_error("calcSHA:open file failed");
        return -1;
    }
    SHA_CTX ctx ;
    SHA1_Init(&ctx);

    //准备一个buffer用于缓冲数据
    char buffer[BUFFER_SIZE];
    int n= fread(buffer,BUFFER_SIZE,1,fp);
    while(n>0)
    {
        SHA1_Update(&ctx,buffer,n);  //更新sha1
        n= fread(buffer,BUFFER_SIZE,1,fp); //持续读取数据
    }
 
     unsigned char hash[SHA_DIGEST_LENGTH];
     SHA1_Final(hash,&ctx);
     //转变为字符串
     for(int i=0;i<SHA_DIGEST_LENGTH;i++)
     {
         sprintf(sha+i*2,"%02x",hash[i]);
     }
     //补充\0
     hash[SHA_DIGEST_LENGTH*2]='\0';

     fclose(fp);

    return 0;
 
}


 
 
/**
 * @brief 从服务器下载版本号
 * @param version 版本号
 * @return 0:下载成功，-1:下载失败
 */
int ota_http_getVersion(AppVersion *version)
{
    // 从连接下载数据对象
    ResponseBody *responseBody=   malloc(sizeof(ResponseBody));
    if (responseBody==NULL)
    {
        log_error("ota_http_getVersion:malloc failed");
        goto INIT_RESPONSE_ERROR;

    }
    
    if(http_curl_getString(VERSION_URL,responseBody)<0)
    {
        log_error("ota_http_getVersion:http_curl_getString failed");
        goto INIT_RESPONSE_ERROR;
    }
    
    // 提取字符串转为json
    cJSON *json=cJSON_Parse(responseBody->str);
    if(json==NULL)
    {
        log_error("ota_http_getVersion:cJSON_Parse failed");
        goto GET_JSON_ERROR;

    } 


    // 从json提取版本号转为AppVersion结构体
    cJSON *major=  cJSON_GetObjectItem(json,"major"  );
    cJSON *minor=  cJSON_GetObjectItem(json,"minor"  );
    cJSON *patch=  cJSON_GetObjectItem(json,"patch"  );
    if(major==NULL||minor==NULL||patch==NULL)
    {
        log_error("ota_http_getVersion:cJSON_GetObjectItem failed");
        goto GET_JSON_VERSION_ERROR;

    }

    version->major=major->valueint;
    version->minor=minor->valueint;
    version->patch=patch->valueint;

    cJSON_Delete(json);

    return version;

GET_JSON_VERSION_ERROR:
    free(version );
GET_JSON_ERROR:  
    cJSON_Delete(json);
GET_RESPONSE_ERROR:  
    free(responseBody);
INIT_RESPONSE_ERROR:
    return -1;
}

/**
 * @brief 从服务器下载ota包
 * @param version 版本号
 * @return 0:下载成功，-1:下载失败
 */
int ota_http_getFirmware(char *filename)
{


     //从连接下载sha码
     ResponseBody *responseBody=   malloc(sizeof(ResponseBody));
     if (responseBody==NULL)
     {
         log_error("ota_http_getFirmware:malloc failed");
         goto INIT_RESPONSE_ERROR;

     }
     if(http_curl_getString(FIRMWARE_SHA_URL,responseBody)<0)
     {
         log_error("ota_http_getFirmware:http_curl_getString failed");
         goto GET_RESPONSE_ERROR;
     }

    // 从连接下载文件
     if(http_curl_downloadFile(FIRMWARE_URL,filename))
     {
         log_error("ota_http_getFirmware:http_curl_downloadFile failed");
         goto DOWNLOAD_FILE_ERROR;
     }
  
      char sha[SHA_DIGEST_LENGTH*2+1];
      calcSHA(filename,sha)  ;

      if(strncmp(sha,responseBody->str,SHA_DIGEST_LENGTH*2)!=0)
      {
           log_error("ota_http_getFirmware:sha not match");
           goto DOWNLOAD_FILE_ERROR;
           return -1;
      }

DOWNLOAD_FILE_ERROR:
 unlink(filename);

GET_RESPONSE_ERROR:
     http_curl_freeResponseBody(responseBody);
INIT_RESPONSE_ERROR:
      return -1;


}


void http_curl_freeResponseBody(ResponseBody *responseBody)
{
    free(responseBody->str);
    free(responseBody);

}

/**
 * @brief 从服务器下载ota包的sha码
 * @param version 版本号
 * @return 0:下载成功，-1:下载失败
 */
int ota_http_getFirmwareSha(AppVersion *version);

 
